package com.immer.session;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;


public class RedisSession extends HashMap implements HttpSession, Serializable {
    private static final long serialVersionUID = 1L;

    private long creationTime;
    private String id;
    private int maxInactiveInterval;
    private long lastAccessedTime = 0L;
    private boolean expired = false;
    private boolean isNew;
    private boolean isDirty = false;
    private transient RedisSessionListener listener;
    private transient HttpServletRequest request;

    public RedisSession(String id) {
        System.out.println("创建 session ,sessionId = " + id);
        this.id = id;
        this.creationTime = System.currentTimeMillis();
        this.isNew = true;
    }

    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    public void setListener(RedisSessionListener listener) {
        this.listener = listener;
    }

    public void setCreationTime(Long creationTime) {
        this.creationTime = creationTime;
    }

    public void setMaxInactiveInterval(Integer maxInactiveInterval) {
        this.maxInactiveInterval = maxInactiveInterval;
    }

    public void setLastAccessedTime(Long lastAccessedTime) {
        this.lastAccessedTime = lastAccessedTime;
    }

    public Boolean getExpired() {
        return expired;
    }

    public void setExpired(Boolean expired) {
        this.expired = expired;
    }

    public Boolean getNew() {
        return isNew;
    }

    public void setNew(Boolean aNew) {
        isNew = aNew;
    }

    public Boolean getDirty() {
        return isDirty;
    }

    public void setDirty(Boolean dirty) {
        isDirty = dirty;
    }

    @Override
    public long getCreationTime() {
        return this.creationTime;
    }

    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public long getLastAccessedTime() {
        return this.lastAccessedTime;
    }

    @Override
    public ServletContext getServletContext() {
        return request.getServletContext();
    }

    @Override
    public void setMaxInactiveInterval(int interval) {
        this.maxInactiveInterval = interval;
    }

    @Override
    public int getMaxInactiveInterval() {
        return this.maxInactiveInterval;
    }

    @Override
    public Object getAttribute(String name) {
        return get(name);
    }

    @Override
    public void setAttribute(String name, Object value) {
        put(name, value);
        notifyAttributeChange();
    }

    @Override
    public void removeAttribute(String name) {
        remove(name);
    }

    @Override
    public Enumeration<String> getAttributeNames() {
        final Iterator iterator = keySet().iterator();
        return new Enumeration<String>() {
            @Override
            public boolean hasMoreElements() {
                return iterator.hasNext();
            }

            @Override
            public String nextElement() {
                return (String) iterator.next();
            }
        };
    }

    @Override
    public void invalidate() {
        expired = true;
        isDirty = true;
        notifyInvalidated();
    }

    @Override
    public boolean isNew() {
        return isNew;
    }

    @Override
    @Deprecated
    public HttpSessionContext getSessionContext() {
        return null;
    }

    @Override
    @Deprecated
    public Object getValue(String name) {
        return get(name);
    }

    @Override
    @Deprecated
    public String[] getValueNames() {
        return (String[]) keySet().toArray();
    }


    @Override
    @Deprecated
    public void putValue(String name, Object value) {
        put(name, value);
        notifyAttributeChange();
    }

    @Override
    @Deprecated
    public void removeValue(String name) {
        remove(name);
    }


    private void notifyAttributeChange() {
        if (listener != null) {
            listener.onAttributeChanged(this);
        }
    }


    private void notifyInvalidated() {
        if (listener != null) {
            listener.onInvalidated(this);
        }
    }

    @Override
    public String toString() {
        return "redis sessionId :" + getId();
    }
}
